/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import br.com.loja.model.entity.Switchable;
import br.com.loja.model.entity.compra.Compra;
import br.com.loja.model.entity.estoque.ItemEstoque;
import br.com.loja.model.entity.venda.Venda;
import br.com.loja.util.reflection.ReflectionUtil;
import br.com.loja.view.swing.Composition;
import br.com.loja.view.swing.model.FormField;
import java.awt.Component;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.GeneratedValue;
import javax.persistence.Transient;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author David Luiz
 */
public class EntityEditorTestOld {

    public EntityEditorTestOld() {
    }

    @Test
    public void leAtributosDaEntidadeQueIraoDaEntidade() {

        Class<?> classEntity = Venda.class;
        List<Field> fields = ReflectionUtil.getAllFields(classEntity);

        assertEquals(9, fields.size());
        assertEquals("dataVenda", fields.get(2).getName());
        assertEquals("dead", fields.get(8).getName());

    }

    @Test
    public void leAtributosDaEntidadeQueIraoSerMapeados() {

        Class<?> classEntity = Venda.class;
        List<Field> fields;

        fields = getMappedFields(classEntity);

        assertEquals(6, fields.size());
        assertEquals("dataVenda", fields.get(1).getName());
    }

    @Test
    public void verificaComponentesAdequadoParaCadaField() {

        Class<?> classEntity = ItemEstoque.class;
        List<Field> fields;
        List<Component> components = new ArrayList<>();

        fields = getMappedFields(classEntity);

        for (Field field : fields) {

            if (field.getAnnotation(GeneratedValue.class) != null) {
                continue;
            }

            Class<?> typeClass;

            if (field.getType().equals(List.class)) {

                ParameterizedType list = (ParameterizedType) field.getGenericType();
                typeClass = (Class<?>) list.getActualTypeArguments()[0];
                boolean isEnumOREntityAggregation = isEnumOrEntityAggregation(typeClass, classEntity);

                if (isEnumOREntityAggregation) {
                    System.out.println(field.getName() + " - " + TO_MANY_AGGREGATION + " LISTA DE SELECAO (" + typeClass.getSimpleName() + ")");
                } else {
                    System.out.println(field.getName() + " - " + TO_MANY_COMPOSITION + " EDITOR DE LISTA(" + typeClass.getSimpleName() + ")");
                }

            } else {

                typeClass = field.getType();
                boolean isEnumOREntityAggregation = isEnumOrEntityAggregation(typeClass, classEntity);

                if (isEnumOREntityAggregation) {
                    System.out.println(field.getName() + " - " + TO_ONE_AGGREGATION + " CAIXA DE SELECAO(" + typeClass.getSimpleName() + ")");
                } else {
                    System.out.println(field.getName() + " - " + TO_ONE_COMPOSITION + " EDITOR DE OBJETO(" + typeClass.getSimpleName() + ")");
                }
            }

        }

        assertEquals(6, components.size());
        assertEquals("JComboBox", components.get(1).getClass().getSimpleName());
    }

    private static final int TO_ONE_COMPOSITION = 12;
    private static final int TO_ONE_AGGREGATION = 11;
    private static final int TO_MANY_COMPOSITION = 22;
    private static final int TO_MANY_AGGREGATION = 21;

    private List<Field> getMappedFields(Class<?> classEntity) {

        List<Field> fields = new ArrayList<>();

        for (Field field : ReflectionUtil.getAllFields(classEntity)) {

            boolean p = Modifier.isStatic(field.getModifiers());
            boolean q = field.getAnnotation(Transient.class) != null;
            boolean s = field.getAnnotation(FormField.class) != null;

            if (p || q || s) {
                continue;
            }

            fields.add(field);

        }
        return fields;
    }

    private boolean isEnumOrEntityAggregation(Class<?> typeClass, Class<?> classEntity) {

        Composition composition = typeClass.getAnnotation(Composition.class);

        boolean isComposition = composition != null ? composition.value().equals(classEntity) : false;
        boolean isEntity = Switchable.class.isAssignableFrom(typeClass);
        boolean isEnum = typeClass.isEnum();

        return (isEntity || isEnum) && !isComposition;
    }

}
